// @ts-ignore
import RequestOptions = UniNamespace.RequestOptions;
// 定义一个默认导出的 EventSource 类


export default class MyEventSource {

    // 成员变量：用于存储连接的 URL
    url: any;

    // 成员变量：用于存储事件监听器的字典
    listeners: any;

    // 成员变量：用于存储请求任务的对象
    requestTask: any;

    // 成员变量：用于存储响应体
    body: object;

    method: RequestOptions['method'];

    header: object;

    lastLine: string | undefined

    // 构造函数，接收 URL 和可选的重试时间参数，默认为 0
    constructor(url: any, body: object = {}, header: object = {}) {
        this.url = url;
        this.listeners = {};
        this.requestTask = null;
        this.body = body;
        this.method = 'POST'
        this.header = header
        this.lastLine = ''
        // 调用 connect 方法进行连接
        this.connect();
    }

    // 连接到服务器的方法
    connect() {
        // 使用 uni.request 发起 GET 请求
        this.requestTask = uni.request({
            url: this.url,
            data: JSON.stringify(this.body),
            header: this.header,
            method: this.method,
            enableChunked: true,
            complete: () => {
                this.emit('complete', {});
            },

        });

        // 注册请求头接收成功事件，发送 'open' 事件
        this.requestTask.onHeadersReceived((res: any) => {
            this.emit('open', res);
        });

        //res.statusCode===200 执行
        // 注册数据块接收事件，调用 handleChunk 处理数据
        this.requestTask.onChunkReceived((res: any) => this.handleChunk(res));
    }

    // 处理数据块的方法
    handleChunk(res: any) {
        // 将数据块转换为 Uint8Array
        const arrayBuffer = res.data;
        const uint8Array = new Uint8Array(arrayBuffer);
        // let utf8decoder = new TextDecoder();
        // let data :any= utf8decoder.decode(uint8Array)
        let data: any = decodeURIComponent(escape(String.fromCharCode(...uint8Array)));
        try {
            data = JSON.parse(data)
            this.emit('error', data.error);
        } catch {
            // 解析事件数据
            this.parseEventData(data);
        }
    }

    // 解析事件数据的方法
    parseEventData(data: string) {

        data = this.lastLine + data
        let lines = data.split('\n');
        if (lines.at(-1) !== '') {
            this.lastLine = lines.pop()
            lines.push('')
        } else {
            this.lastLine = ''
        }
        const result: any = {};
        // 遍历每一行数据
        lines.forEach(line => {
            if (line.length === 0) {
                return
            }
            // 将每行数据按冒号分割成键值对
            const [key, value] = line.trim().split(':');
            // 如果键为 'data'，则尝试解析 JSON 数据，否则直接存储值
            if (key === 'data') {
                const data = line.substring(5).trim();
                try {
                    result[key] = JSON.parse(data);
                } catch (e) {
                    result[key] = data;
                }
            } else {
                result[key] = value;
            }
            // 发送相应事件，携带解析后的数据
            this.emit('message', {data: result.data});
        });


        return result;
    }

    // 添加事件监听器的方法
    addEventListener(event: string | number, callback: any) {
        // 如果当前事件没有对应的监听器数组，创建一个空数组
        if (!this.listeners[event]) {
            this.listeners[event] = [];
        }
        // 将回调函数添加到监听器数组
        this.listeners[event].push(callback);
    }

    // 触发事件的方法
    emit(event: string, data: any) {
        // 如果存在对应事件的监听器数组，逐个调用回调函数
        if (this.listeners[event]) {
            this.listeners[event].forEach((callback: (arg0: UniApp.RequestSuccessCallbackResult) => void) => {
                callback(data);
            });
        }
    }

    // 关闭连接的方法
    close() {
        // 如果存在请求任务，中断请求
        if (this.requestTask) {
            this.requestTask.abort();
        }
    }
}
